package com.example.online_exam_system.logic.impl;

import com.alibaba.fastjson.JSON;
import com.example.online_exam_system.commons.Result;
import com.example.online_exam_system.commons.TableResult;
import com.example.online_exam_system.dto.QuestionsDto;
import com.example.online_exam_system.dto.RegisterDto;
import com.example.online_exam_system.dto.ScoreDto;
import com.example.online_exam_system.entity.StuExam;
import com.example.online_exam_system.entity.Student;
import com.example.online_exam_system.entity.TestPage;
import com.example.online_exam_system.logic.IQuestionsInfoService;
import com.example.online_exam_system.logic.IStudentLogicService;
import com.example.online_exam_system.service.*;
import com.example.online_exam_system.utils.HAUtils;
import com.example.online_exam_system.utils.KaptchaValid;
import com.example.online_exam_system.utils.MD5Utils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.SessionScope;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author lianglong
 * @create 2021-11-26-15:36
 * @describe
 */
@Slf4j
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class StudentLogicServiceImpl implements IStudentLogicService {
    @Autowired
    HttpServletRequest request;

    @Autowired
    StudentService studentService;

    @Autowired
    StuSubService stuSubService;

    @Autowired
    ExamService examService;

    @Autowired
    SubjectService subjectService;

    @Autowired
    TeacherService teacherService;

    @Autowired
    TestPageService testPageService;

    @Autowired
    TestQuestionsService testQuestionsService;

    @Autowired
    StuExamService stuExamService;


    @Override
    public int pwdVerify2(Map<String, Object> inParam) {
        String pwd = MD5Utils.getMD5(MapUtils.getString(inParam,"password"));
        String password = studentService.getPassword(inParam);
        if(pwd.equals(password)){
            return 1;
        }else{
            return 0;
        }
    }

    @Override
    public Result loginCheck(@RequestBody Map<String, Object> inParam) {
        HttpSession session = request.getSession();
        //判断验证码是否有效
        if (KaptchaValid.isRelsase(request, MapUtils.getString(inParam, "kapText"))) {
            //验证通过   检查用户名密码是否正确
            //密码加密
            String pwd = MD5Utils.getMD5(MapUtils.getString(inParam,"password"));
            inParam.put("password",pwd);
            List<Map<String, Object>> list = studentService.queryByuserName(inParam);
            //检查数据库是否存在对应用户
            //存在
            if (list != null && list.size() > 0) {
                //将用户姓名存放至session中
                String username = MapUtils.getString(inParam, "username");
                session.setAttribute("username", username);
                //将用户身份存放至session中
                session.setAttribute("identify","student");
                //获取页面展示信息
                List<Map<String, Object>> studentInfo = this.getStudentInfo(username);
                session.setAttribute("studentInfo",studentInfo.get(0));
                return Result.ok().msg("欢迎你," + username + "同学").data(username);
            }
            //不存在
            return Result.err().msg("用户名密码不正确");
        } else {
            return Result.err().msg("验证码错误");
        }
    }

    @Override
    public Result regCheck(Map<String, Object> inParam) {
        //根据用户名判断是否有用户已经注册
        List<Map<String, Object>> list = studentService.queryByuserName(inParam);
        if (list == null || list.size() == 0) {
            //将用户信息添加至数据库
            //密码加密
            RegisterDto registerDto = JSON.parseObject(JSON.toJSONString(inParam), RegisterDto.class);
            registerDto.setPassword(MD5Utils.getMD5(registerDto.getPassword()));
            registerDto.setRegtime(LocalDateTime.now());
            int insert = studentService.insert(registerDto);
            log.debug("注册成功！！！！！！！！！！！！！！");
            if (insert > 0) {
                return Result.ok().msg("注册成功");
            }else{
                return Result.err().msg("注册失败  请联系系统管理员");
            }
        } else {
            return Result.err().msg("该用户存在  不允许再次注册");
        }
    }



    @Override
    public List<Map<String,Object>> getStudentInfo(String username){
        List<Map<String,Object>> result = new ArrayList<>();
        //获取用户基本信息
        Map<String, Object> studentInfo = studentService.getStudentInfo(username);
        result.add(studentInfo);
        //获取学生id
        String userId = MapUtils.getString(studentInfo,"studentid");
        //根据学生id查找所选科目名，教师名
        List<Map<String,Object>> list = stuSubService.getSubjectInfo2(userId);
        Map<String,Object> subinfo = new HashMap<>();
        subinfo.put("subjectinfo",list);
        result.add(subinfo);
        //根据学生id查找考试信息（试卷id，试卷成绩）
//        List<Map<String, Object>> examInfo = examService.getExamInfo(userId);
        // TODO: 2021/11/27 根据试卷id查找试卷名称
        //将试卷信息存放至examinfo
        return result;
    }

    @Override
    public TableResult getstuexam() {
        List<Map<String,Object>> result = new ArrayList<>();
        //从session中取username
        HttpSession session = request.getSession();
        String username = (String)session.getAttribute("username");
        //根据username获取userid学生id
        Map<String, Object> studentInfo = studentService.getStudentInfo(username);
        String studentId = MapUtils.getString(studentInfo,"studentid");
        List<Map<String,Object>> list = stuSubService.getSubjectInfo(studentId);
        int i =0 ;
        for(Map<String,Object> map : list){
            String subjetId = MapUtils.getString(map,"subjectid");
            String teacherId = MapUtils.getString(map,"teacherid");
            String subjectName = MapUtils.getString(subjectService.getSubjectNameByIdAready(subjetId),"subjectname");
            String teacherName = MapUtils.getString(teacherService.queryByUserId(teacherId),"realname");
            map.put("subjectName",subjectName);
            map.put("teacherName",teacherName);
            Map<String,Object> inParam = new HashMap<>();
            inParam.put("subjectId",subjetId);
            inParam.put("teacherId",teacherId);
            List<Map<String, Object>> examInfo = testPageService.getExamInfo(inParam);

            for(Map<String,Object> map2:examInfo){
                HashMap<String,Object> map3 = new HashMap<>();
                map3.putAll(map);
                map3.putAll(map2);
                result.add(map3);
                log.info(result.get(i).toString());
                i++;
            }
        }
        int size = result.size();
        String count = size +"";
        return new TableResult().code(0).msg("获取数据成功").count(count).data(result);
    }

    @Override
    public List<Map<String, Object>> ExamDeatials(String username,String testId) {
        List<Map<String, Object>> pageDetail = testPageService.getPageDetail(testId);
        log.debug("试卷信息为："+pageDetail);
        Map<String,Object> map = pageDetail.get(0);
        String startTime = MapUtils.getString(map,"start_time");
        String endTime = MapUtils.getString(map,"end_time");
        String teacherId = MapUtils.getString(map,"teacherid");
        String testName = MapUtils.getString(map,"testname");
        String subjectId = MapUtils.getString(map,"subjectid");
        String testid = MapUtils.getString(map,"testid");
        Map<String,Object> examinfo1 = new HashMap<>();
        examinfo1.put("startTime",startTime);
        examinfo1.put("endTime",endTime);
        examinfo1.put("teacherId",teacherId);
        examinfo1.put("testName",testName);
        examinfo1.put("subjectId",subjectId);
        examinfo1.put("testId",testid);
        examinfo1.put("username",username);
        List<Map<String,Object>> questions = new ArrayList<>();
        for(Map<String,Object> map2 : pageDetail){
            String questionid = MapUtils.getString(map2,"questionid");
            Map<String,Object> questionInfo = testQuestionsService.getQuestionsByQuestionId(questionid);
            String type = MapUtils.getString(questionInfo, "type");
            if(type.equals("单选题")){
                questionInfo.put("type2","1");
            }else if(type.equals("填空题")){
                questionInfo.put("type2","2");
            }else if(type.equals("简答题")){
                questionInfo.put("type2","3");
            }
            questions.add(questionInfo);
        }
        List<Map<String,Object>> result = new ArrayList<>();
        result.add(examinfo1);
        result.addAll(questions);
        log.debug("result:"+result);
        return result;
    }

    @Override
    public Result submmitExam(Map<String, Object> map) {
        //{testId=16, username=lianglong, 16=A, 17=没有区别, 18=哈哈哈, 19=对的, 20=没有用, 21=必须的, 22=A, 23=A}
        String userName = MapUtils.getString(map,"username");
        Map<String, Object> studentInfo = studentService.getStudentInfo(userName);
        Integer userId = MapUtils.getInteger(studentInfo,"studentid");
        Integer testId = MapUtils.getInteger(map,"testId");
        map.remove("testId");
        map.remove("username");
        ArrayList<StuExam> list = new ArrayList<>();
        map.forEach((key,value)->{
            int key2 = Integer.parseInt(key);
            String value2 = String.valueOf(value);
            BiFunction<Integer,String, StuExam> biFunction = StuExam::new;
            list.add(biFunction.apply(key2,value2));
        });
        list.stream().forEach(s->{
            s.setUserid(userId);
            s.setTestid(testId);
            System.out.println(s);
        });
        stuExamService.batchinsert(list);
        return new Result().msg("交卷成功").success(true).data("成功");
    }

    @Override
    public TableResult queryScore1(String username) {
        Map<String, Object> studentInfo = studentService.getStudentInfo(username);
        String userId = MapUtils.getString(studentInfo,"studentid");
        List<StuExam> list1 = stuExamService.queryExamByuserId(userId);
        List<ScoreDto> list2 = new ArrayList<>();
        Set<Integer> set = new TreeSet<>();
        list1.forEach(stuExam -> {
            ScoreDto scoreDto = new ScoreDto();
            String testid = stuExam.getTestid().toString();
            String userid = stuExam.getUserid().toString();
            String testname = MapUtils.getString(testPageService.getPageDetail(testid).get(0),"testname");
            String score = (stuExam.getScore()) == null?"0":(stuExam.getScore());
            if(set.contains(Integer.parseInt(testid))){
                list2.forEach(scoreDto1 -> {
                    if(scoreDto1.getTestid().equals(testid)){
                        int scores1 =Integer.parseInt(scoreDto1.getScores());
                        scores1 += Integer.parseInt(score);
                        scoreDto1.setScores(scores1+"");
                    }
                });
            }else{
                scoreDto.setTestid(testid);
                scoreDto.setTestname(testname);
                scoreDto.setUserid(userid);
                scoreDto.setScores(score);
                list2.add(scoreDto);
            }
            set.add(Integer.parseInt(testid));

        });
        log.debug("成绩列表"+list2);
        TableResult result = new TableResult();
        String size = list2.size()+"";
        result.code(0).msg("获取数据成功").count(size).data(list2);
        return result;
    }

    @Override
    public int updateStudentInfo(Map<String, Object> inParam) {
        String password  = MD5Utils.getMD5(MapUtils.getString(inParam,"password")) ;
        inParam.put("password",password);
        int i = studentService.updateStudentInfo(inParam);
        int j = stuSubService.deleteTeaSubByStudentId(inParam);
        String studentId = MapUtils.getString(inParam,"studentid");
        List<String> stusubs = HAUtils.castList(inParam.get("subjects"),String.class);
        List<Map<String,Object>> list2 = new ArrayList<>();
        stusubs.forEach(string->{
            Map<String,Object> map = new HashMap<>();
            String[] strs = string.split("-");
            String subjectname = strs[0];
            String subjectId = subjectService.getSubjectIdByname(subjectname);
            String realname = strs[1];
            String teacherId = teacherService.getTeacherId(realname);
            map.put("teacherid",teacherId);
            map.put("subjectid",subjectId);
            map.put("studentid",studentId);
            list2.add(map);
        });
        log.debug(""+list2);
        int k = stuSubService.batchInsert(list2);
        if(i>0 && j>0 && k>0){
            return 1;
        }else{
            return 0;
        }

    }

    @Override
    public List<Map<String, Object>> getStudentInfo2(String username) {
        List<Map<String,Object>> result = new ArrayList<>();
        //获取用户基本信息
        Map<String, Object> studentInfo = studentService.getStudentInfo(username);
        result.add(studentInfo);
        //获取学生id
        String userId = MapUtils.getString(studentInfo,"studentid");
        //已选的科目和教师
        List<Map<String,Object>> list = stuSubService.getSubjectInfo2(userId);
        Map<String,Object> subinfo = new HashMap<>();
        List<String> list1 = new ArrayList<>();
        list.forEach(subtea->{
            String key = MapUtils.getString(subtea,"subjectname");
            String value = MapUtils.getString(subtea,"realname");
            list1.add(key+"-"+value);
        });
        subinfo.put("subjectinfo",list1);
        result.add(subinfo);
        //所有的
        List<Map<String, Object>> allsubtea = this.getAllsubtea();
        Map<String,Object> subteainfo = new HashMap<>();
        List<String> list2 = new ArrayList<>();
        allsubtea.forEach(subtea->{
            String key = MapUtils.getString(subtea,"subjectname");
            String value = MapUtils.getString(subtea,"realname");
            list2.add(key+"-"+value);
        });
        subteainfo.put("subteainfo",list2);
        result.add(subteainfo);
        return result;
    }

    @Override
    public List<Map<String, Object>> getAllsubtea() {
        return stuSubService.getAllsubtea();
    }

    @Override
    public List<Map<String, Object>> modifyStudentInfo() {
        HttpSession session = request.getSession();
        String username = (String)session.getAttribute("username");
        List<Map<String, Object>> studentInfo2 = this.getStudentInfo2(username);
        return studentInfo2;
    }

    @Override
    public List<Map<String, Object>> ExamDeatials2(String userId, String testId) {
        Map<String,Object> map = stuExamService.getExamInfo(userId,testId);
        List<Map<String, Object>> list2 = stuExamService.getExamInfo2(userId,testId);
        ListIterator<Map<String, Object>> mapListIterator = list2.listIterator();
        while(mapListIterator.hasNext()){
            Map<String, Object> next = mapListIterator.next();
            if(MapUtils.getString(next,"score") == null){
                next.put("score","暂未评阅");
            }
        }
        List<Map<String,Object>> list = new ArrayList<>();
        list.add(map);
        Map<String,Object> map2 = new HashMap<>();
        map2.put("list2",list2);
        list.add(map2);
        return list;
    }

    @Override
    public List<Map<String, Object>> getStuAll() {
        List<Map<String, Object>> stuAll = studentService.getStuAll();
        return stuAll;
    }


}
